#include "main.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>

volatile uint32_t sysTimeTickMs = 0;


#if (UART_Debug_EN)

//u32 uart_data_in = 0;
//u32 uart_data_out = 0;
//u8 uart_buf[UART_BUF_SIZE];

void UART_Debug_Init(void)
{
	
	uint32_t  BuadRate;
	BuadRate = 2000000;
		
	/*
	(1) 设置UARTx模式
	*/
	UART_ConfigRunMode(UART1, BuadRate, UART_WLS_8, UART_PARITY_NONE,UART_STOP_BIT_1);
	/*
	(2) 开启UARTx时钟
	*/	
	SYS_EnablePeripheralClk(SYS_CLK_UART1_MSK);
	/*
	(3) 开启UARTx输出
	*/	
	SYSCON->IOP46CFG = SYS_IOCFG_P46_TXD1;
	//SYS_SET_IOCFG(IOP43CFG, SYS_IOCFG_P43_TXD1);		 
	/*
	(4) 开启FIFO
	*/
	UART1->FCR = 0x07;
	
	disp_Title();


}



//extern volatile Union_Fault	u_Fault_Flag;

void TxByte(unsigned char ch)
{
	while(!(UART1->LSR&UART_LSR_THRE_Msk));
	UART1->THR = ch;
}
  
 void TxString(char *str)
 {
	 while(*str != 0) {TxByte(*str); str++;}
 }
  
 void print_u(uint32_t uData,int num)
 {
	  char out[10];
	  int i=0;
	  int j;
	  do{
		  out[i] = 0x30+uData%10;
		  i++;
		  uData = uData/10;
		  if(i>10) break;
	  }while (uData != 0);
  
	  if(num > 0){
		  for(j = i; j<num;j++) out[j] = 0x30;
		  i = num;
	  }
  
	  while(i > 0){
		  TxByte(out[i-1]);
		  i--;
	  }
 }
  
 void print_x(uint32_t uData,int num)
 {
	  char out[8];
	  int i=0;
	  int j;
	  do{
		  out[i] = uData%16;
		  if(out[i]<10) out[i] += 0x30;
		  else out[i] += ('A'-10);
		  i++;
		  uData = uData/16;
		  if(i>8) break;
	  }while (uData != 0);
  
	  if(num > 0){
		  for(j = i; j<num;j++) out[j] = 0x30;
		  i = num;
	  }
  
	  TxByte('0');
	  TxByte('x');
	  while(i > 0){
		  TxByte(out[i-1]);
		  i--;
	  }
 }
  
 void print_d(int iData,int num)
 {
	  
	  if(iData < 0){
		  iData = (~iData);
		  iData++;
		  TxByte('-');
	  }
  
	  print_u((uint32_t)iData,num);
 }

  /*
  这里我们用到了ANSI的ESC屏幕控制，其中可以更改输出颜色信息等。
  我们一般使用到的格式如下：<ESC>[{option 1};{option 2};{option 3};...{option n-1};{option n}m
  在echo输出信息时需要添加-e选项支持转义字符。
  <ESC>在输出信息中通常的表示形式有三种：\033、\x1b、\e。
  <ESC>后跟上屏幕控制的选项：以[标识开头、以m标识结尾。
  期间可以跟许多的屏幕控制选项：
  0：所有属性恢复默认
  1：高亮显示
  4：添加下划线
  5：闪烁
  7：反隐（将字体颜色和背景色互换）
  8: 消隐
  30~38：设置前景色（字体颜色）。（30黑色、31红色、32绿色、33黄色、34蓝色、35紫色、36青色、37灰色、38淡蓝色）
  40~48：设置背景色（字体背景）。（40黑色、41红色、42绿色、43黄色、44蓝色、45紫色、46青色、47灰色、48淡蓝色）
  2J：清屏 0J: 清除光标位置到屏幕末尾，1J: 清除光标位置到屏幕开始，3J: 清除整个屏幕并删除回滚缓冲区。

  /033[nA 光标上移n行

	/033[nB 光标下移n行

	/033[nC 光标右移n行

	/033[nD 光标左移n行

	/033[y;xH设置光标位置

	/033[K 清除从光标到行尾的内容

	/033[s 保存光标位置
	
	/033[u 恢复光标位置

	/033[?25l 隐藏光标

	/033[?25h 显示光标

  */

  void myPrintfX(uint32_t disp,const char *fmt,...)
  {

	  uint32_t num = 0;
	  int format_num = 0;
	  uint8_t format_flag = 0;
	  uint32_t hour,min,sec,ms;

	  if(disp & TIMESTAMP_MASK){
	  		TxString("\x1b[0m");
	  		ms = sysTimeTickMs%1000;
	  		sec = sysTimeTickMs/1000;
			min = sec/60;
			hour = min/60;
			sec = sec%60;
			min = min%60;
	  	TxByte('[');
			//TxChar(' ');
			print_u(hour,2);
			TxByte(':');
			print_u(min,2);
			TxByte(':');
			print_u(sec,2);
			TxByte('.');
			print_u(ms,3);
			//TxChar(' ');
			TxByte(']');
			TxByte(' ');
			TxString("\x1b[37m\x1b[1m");
			
	  }

	  switch(disp & COLOR_MASK){
		case COLOR_RED:
			TxString("\x1b[31m\x1b[1m");
			break;
		case COLOR_GREEN:
			TxString("\x1b[32m\x1b[1m");
			break;
		case COLOR_YELLOW:
			TxString("\x1b[33m\x1b[1m");
			break;
		case COLOR_BLUE:
			TxString("\x1b[34m\x1b[1m");
			break;
		case COLOR_PURPLE:
			TxString("\x1b[35m\x1b[1m");
			break;
		case COLOR_CYAN:
			TxString("\x1b[36m\x1b[1m");
			break;
		case COLOR_WHITE:
			TxString("\x1b[37m\x1b[1m");
			break;
		default:
			break;
	  }

	  if(disp & BLINK_MASK){
		TxString("\x1b[5m");
	  }
	  
	  va_list args;
	  va_start(args,fmt);
  
	  //va_arg(args,char *);
	  while(*fmt){
		  switch(*fmt){
			  case '%':   
			  {
				  if(format_flag) {TxByte(*fmt); format_flag = 0; break;}
				  format_num = 0;
				  format_flag = 1;
				  fmt++;
				  switch(*fmt){
					  case '0':
					  {
						  
  
						  while(1){
							  fmt++;
							  if(*fmt >= 0x30 && *fmt <= 0x39){
								  format_num *= 10;
								  format_num += *fmt-0x30;
							  }else{
								  fmt--;
								  break;
							  }
						  }
						  
					  }
						  break;
					  
					  
					  default:
						  fmt--;
						  break;
				  }
				  
				  
			  }
				  break;
			  case 's':
			  case 'S':
			  {
				  if(format_flag){
					  char *str = va_arg(args,char*);
					  TxString(str);
					  num++;
				  }else TxByte(*fmt);
				  format_flag = 0;
			  }
				  break;
			  case 'd':
			  case 'D':
			  {
				  if(format_flag){
					  int vlaue = va_arg(args,int);
					  
					  num++;
  
					  print_d(vlaue,format_num);
				  }else TxByte(*fmt);
				  format_flag = 0;
			  }
				  break;
			  case 'u':
			  case 'U':
			  {
				  if(format_flag){
					  uint32_t vlaue = va_arg(args,uint32_t);
					  print_u(vlaue,format_num);
					  num++;
				  }else TxByte(*fmt);
				  format_flag = 0;
			  }
				  break;
			  case 'x':
			  case 'X':
			  {
				  if(format_flag){
					  uint32_t vlaue  = va_arg(args,uint32_t);
					  
					  print_x(vlaue,format_num);
					  num++;
				  }else TxByte(*fmt);
				  format_flag = 0;
			  }
				  break;
			  default:
				  format_flag = 0;
				  TxByte(*fmt);
				  break;
		  }
		  
		  fmt++;
	  }
	  
	  va_end(args);

	  TxString("\x1b[37m\x1b[1m");

	  TxByte('\r');
	  TxByte('\n');
  
 
  
 }

uint8_t M1state[MSTATE_BUF_SIZE];
uint8_t M1stateIn = 0;
uint8_t M1stateOut = 0;
	
void putM1state(void)
{
	//static M1States lastM1State = M1_UNKNOWN;
	//if(M1_State != lastM1State)
	{
		//lastM1State = M1_State;
		M1state[M1stateIn] = M1_State;
		M1stateIn++;
		if(M1stateIn >= MSTATE_BUF_SIZE) M1stateIn = 0;
		if(M1stateIn == M1stateOut) {
			M1stateOut++;
			if(M1stateOut >= MSTATE_BUF_SIZE) M1stateOut = 0;
		}
			
	}
}

uint8_t M2state[MSTATE_BUF_SIZE];
uint8_t M2stateIn = 0;
uint8_t M2stateOut = 0;
	
void putM2state(void)
{
	//static M2States lastM2State = M2_UNKNOWN;
	//if(M2_STATE != lastM2State)
	{
		//lastM2State = M2_STATE;
		M2state[M2stateIn] = M2_STATE;
		M2stateIn++;
		if(M2stateIn >= MSTATE_BUF_SIZE) M2stateIn = 0;
		if(M2stateIn == M2stateOut) {
			M2stateOut++;
			if(M2stateOut >= MSTATE_BUF_SIZE) M2stateOut = 0;
		}
			
	}
}

//u16 Err[ERR_BUF_SIZE];
//u8 ErrIn = 0;
//u8 ErrOut = 0;

//void putError(void)
//{
//	static u16 lastErr = 0xff;
//	
//	if(lastErr != u_Fault_Flag.Byte){
//		lastErr = u_Fault_Flag.Byte;
//		Err[ErrIn] = u_Fault_Flag.Byte;
//		ErrIn++;
//		if(ErrIn >= ERR_BUF_SIZE) ErrIn = 0;
//		if(ErrIn == ErrOut){
//			ErrOut++;
//			if(ErrOut >= ERR_BUF_SIZE) ErrOut = 0;
//		}
//			
//	}

/*
		
#define Fault_Flag		    				u_Fault_Flag.Byte
#define	Fault_ShortCircuit				u_Fault_Flag.Bits.Bit0
#define	Fault_UnderVoltage				u_Fault_Flag.Bits.Bit7	
#define	Fault_StartFail						u_Fault_Flag.Bits.Bit6 
#define	Fault_OverVoltage					u_Fault_Flag.Bits.Bit5 
//#define	Fault_TorgueLoss					u_Fault_Flag.Bits.Bit4 
#define	Fault_OverCurrent					u_Fault_Flag.Bits.Bit3  0x08
#define	Fault_PhaseLoss						u_Fault_Flag.Bits.Bit2 
#define	Fault_Block							u_Fault_Flag.Bits.Bit1
//0301
#define	Fault_OverTemp						u_Fault_Flag.Bits.Bit8 
#define Fault_VCC_UV						u_Fault_Flag.Bits.Bit9
#define Fault_IPM_ERROR						u_Fault_Flag.Bits.Bit10



*/

//}

void printLoop(void)
{
	static uint8_t last_Fault_Flag = 0xff;

	if(last_Fault_Flag != Fault_Flag)
	{
		last_Fault_Flag = Fault_Flag;
		if(Fault_Flag == 0)log_d("---> u_Fault_Flag: %04X",Fault_Flag);
		else log_e("---> u_Fault_Flag: %04X",Fault_Flag);
	}
	
	if(M1stateIn != M1stateOut){
		log_d("M1_STATE: %u",M1state[M1stateOut]);
		M1stateOut++;
		if(M1stateOut >= MSTATE_BUF_SIZE) M1stateOut = 0;
	}
	
	if(M2stateIn != M2stateOut){
		log_i("M2_STATE: %u",M2state[M2stateOut]);
		M2stateOut++;
		if(M2stateOut >= MSTATE_BUF_SIZE) M2stateOut = 0;
	}

//			
//	putError();
//	if(ErrIn != ErrOut){
//		if(Err[ErrOut] == 0)log_d("---> u_Fault_Flag: %04X",Err[ErrOut]);
//		else log_e("---> u_Fault_Flag: %04X",Err[ErrOut]);
//		ErrOut++;
//		if(ErrOut >= ERR_BUF_SIZE) ErrOut = 0;
//	}
	
	{
		static uint8_t last_gBrakeStatus = 0;
		if(last_gBrakeStatus != gBrakeStatus)
		{
			last_gBrakeStatus = gBrakeStatus;
			log_v("gBrakeStatus = %u",gBrakeStatus);
		}
	}

	if(TimeFlag_1S)
	{
		TimeFlag_1S = 0; 

		//log_v("ADVal[CH_IBUS] = %u",ADVal[CH_IBUS]);

		//log_v("Basic.Ibus = %dmA",Basic.Ibus);

//		log_i("Mech_Speed = %u",Basic.Mech_Speed);
//		log_d("Angle = %u",SC60228_Data);
//		
//		log_i("u_MotorRmpSet = %u",u_MotorRmpSet);
//		log_i("M1_Flag.RunStop = %u",M1_Flag.RunStop);
//		log_i("gTrigStatus = %u",gTrigStatus);
//		log_i("M1_Speed_Ctrl_Mode = %u",M1_Speed_Ctrl_Mode);
//		//log_i("Position_Change_Time = %u\r\n",Position_Change_Time);
		//log_w("gearNow = %u",gearNow);
//		log_w("speedChangeTime = %u",speedChangeTime);

		#if 0

		log_d("Vbus = %u",Basic.Vbus);
		 
		Basic.Mech_Speed = PLL_Speed;
		Basic.Mech_Speed *= 60;
		Basic.Mech_Speed >>= 9;
		Basic.Mech_Speed /= Motor.PPN;
		//log_i("PLL_Speed = %u",PLL_Speed);
		log_i("Mech_Speed = %u",Basic.Mech_Speed);
		log_i("SC60228_Data = %u",SC60228_Data);
		#endif
		//log_i("Motor_Iq_Set_Buf = %u",Motor_Iq_Set_Buf); 
		//log_i("ADVal[CH_HALL] = %u",ADVal[CH_HALL]);
		

//			{
//				#if 0
//				static u32 ref = (((32767*HW_PHASE_RES*HW_AMP_GAIN_IP)/(HW_ADC_REF-HW_AMP_REF_IP)));
//				u32 Iq;

//				Iq = stru_Curr_dq.Iq*1000;
//				Iq = Iq / ref;

//				log_i("stru_Curr_dq.Iq = %u",Iq); 

//				#endif

//			#if 0

//			volatile u32 actualVbus;

//			actualVbus = Basic.Vbus;
//			actualVbus *= (HW_VBUS_VOLT*1000);
//			actualVbus /= 16384;

//			log_i("actualVbus = %u",actualVbus);
//			#endif
//			
//			//log_i("V_VCC = %u",Basic.V_VCC); 
//			

//			log_d("SPI_Data = %04x",SPI_Data);
//			
//			log_d("SC_Speed = %u",SC60228_speed);
//			
//			

//			//log_i("Basic.Speed_Ke = %u",Basic.Speed_Ke); 

//			//log_i("gKeyAD = %u",gKeyAD);
//			//log_i("gSWAD = %u",gSWAD);
//			//log_i("gKeyADSample = %u",gKeyADSample);

//			}
	}

//}

//void printSystemState(void)
//{
//	static u8 last_SYSTEM_STATE = 0xff;
//	//static u16 last_u_Fault_Flag = 0xffff;
//	
//	if(last_SYSTEM_STATE != SYSTEM_STATE){
//		last_SYSTEM_STATE = SYSTEM_STATE;
//		log_w("SYSTEM_STATE: %u",SYSTEM_STATE);
//	}

//	/*
//	if(last_u_Fault_Flag != u_Fault_Flag.Byte)
//	{
//		last_u_Fault_Flag = u_Fault_Flag.Byte;
//		if(u_Fault_Flag.Byte == 0) log_d("---> u_Fault_Flag: %04X",u_Fault_Flag.Byte);
//		else log_e("u_Fault_Flag: %04X",u_Fault_Flag.Byte);
//		
//	}
//	*/
}


void disp_Title(void)
{
	TxString("\x1b[2J\x1b[3J\x1b[1;1H\x1b[0m\x1b[7m");	// \f 换页 
	w_printf("************ %s ************************ %s *************",Product_Name,Company_Name);
	w_printf("                   V202 Compiled: %s,%s                   ",__DATE__,__TIME__);
	w_printf("*************************************************************************");
	TxString("\x1b[0m");

}


#endif

#if(UART_Debug_EN == 0)

void UART_Debug_Init(void) {};
void TxByte(unsigned char ch) {};	
void TxBufChar(unsigned char ch) {}	
void TxString(char *str) {}
void putMstate(void) {}
void putError(void) {}
void uart_flush(void) {}
void printLoop(void) {}
void printSystemState(void) {}
void myPrintfX(uint32_t disp,const char *fmt,...) {}
void disp_Title(void) {}

	
#endif






  

